import os
import platform
import logging

logger = logging.getLogger()


class PathUtils:
    """
    路径工具类，用于处理跨平台路径问题
    提供统一的路径处理方法，兼容Windows和Linux/macOS
    """

    @staticmethod
    def get_platform():
        """获取当前操作系统平台"""
        return platform.system().lower()

    @staticmethod
    def is_windows():
        """判断是否为Windows系统"""
        return PathUtils.get_platform() == "windows"

    @staticmethod
    def is_linux():
        """判断是否为Linux系统"""
        return PathUtils.get_platform() == "linux"

    @staticmethod
    def is_macos():
        """判断是否为macOS系统"""
        return PathUtils.get_platform() == "darwin"

    @staticmethod
    def normalize_path(path):
        """
        标准化路径，将路径分隔符转换为当前系统的分隔符

        Args:
            path: 需要标准化的路径

        Returns:
            标准化后的路径
        """
        if path is None:
            return None

        # 将所有反斜杠转换为正斜杠
        normalized = path.replace("\\", "/")

        # 如果是Windows系统，再转换回Windows风格
        if PathUtils.is_windows():
            normalized = normalized.replace("/", "\\")

        return normalized

    @staticmethod
    def join_path(*paths):
        """
        连接路径，使用os.path.join并标准化结果

        Args:
            *paths: 需要连接的路径部分

        Returns:
            连接后的标准化路径
        """
        if not paths:
            return ""

        # 先标准化每个路径部分
        normalized_parts = [
            PathUtils.normalize_path(p) if isinstance(p, str) else p for p in paths
        ]

        # 使用os.path.join连接
        joined = os.path.join(*normalized_parts)

        # 再次标准化结果
        return PathUtils.normalize_path(joined)

    @staticmethod
    def get_absolute_path(path):
        """
        获取绝对路径

        Args:
            path: 相对或绝对路径

        Returns:
            绝对路径
        """
        if not path:
            return None

        # 标准化路径
        normalized = PathUtils.normalize_path(path)

        # 转换为绝对路径
        absolute = os.path.abspath(normalized)

        # 再次标准化结果
        return PathUtils.normalize_path(absolute)

    @staticmethod
    def get_project_root():
        """
        获取项目根目录的绝对路径

        Returns:
            项目根目录的绝对路径
        """
        # 获取当前文件所在目录
        current_dir = os.path.dirname(os.path.abspath(__file__))

        # 向上查找，直到找到项目根目录
        # 项目根目录通常包含一些特定文件，如 flask_server.py, requirements.txt 等
        root_dir = current_dir
        while root_dir and not os.path.exists(
            os.path.join(root_dir, "flask_server.py")
        ):
            parent = os.path.dirname(root_dir)
            if parent == root_dir:  # 已经到达文件系统根目录
                # 如果找不到特定文件，则返回utils的父目录作为备选
                return PathUtils.normalize_path(os.path.dirname(current_dir))
            root_dir = parent

        return PathUtils.normalize_path(root_dir)

    @staticmethod
    def ensure_dir_exists(directory):
        """
        确保目录存在，如果不存在则创建

        Args:
            directory: 目录路径

        Returns:
            标准化后的目录路径
        """
        if not directory:
            return None

        # 标准化路径
        normalized = PathUtils.normalize_path(directory)

        # 确保目录存在
        if not os.path.exists(normalized):
            try:
                os.makedirs(normalized)
                logger.info(f"创建目录: {normalized}")
            except Exception as e:
                logger.error(f"创建目录失败: {normalized}, 错误: {str(e)}")

        return normalized

    @staticmethod
    def get_relative_path(path, base_path=None):
        """
        获取相对路径

        Args:
            path: 需要转换的路径
            base_path: 基准路径，默认为项目根目录

        Returns:
            相对路径
        """
        if not path:
            return None

        # 如果未提供基准路径，使用项目根目录
        if not base_path:
            base_path = PathUtils.get_project_root()

        # 标准化路径
        normalized_path = PathUtils.normalize_path(path)
        normalized_base = PathUtils.normalize_path(base_path)

        # 转换为绝对路径
        abs_path = os.path.abspath(normalized_path)
        abs_base = os.path.abspath(normalized_base)

        # 计算相对路径
        try:
            relative = os.path.relpath(abs_path, abs_base)
            return PathUtils.normalize_path(relative)
        except ValueError:
            # 如果路径在不同驱动器上（Windows），返回绝对路径
            logger.warning(
                f"无法计算相对路径，路径可能在不同驱动器: {abs_path}, 基准: {abs_base}"
            )
            return PathUtils.normalize_path(abs_path)
